package com.terrier.utils
{
    import flash.events.Event;
    import flash.net.URLLoader;
    import flash.net.URLLoaderDataFormat;
    import flash.net.URLRequest;
    import flash.utils.ByteArray;
    import flash.utils.Dictionary;

    /**
     * 汉字转换拼音的工具
     * @author Jarvis.weng
     */
    public class WxPinyinUtility
    {
        private static var s_pinyinDict:Dictionary = new Dictionary();

        private static var s_dataParser:DataParser;

        static public function initialize(dataURL:String, completeCallback:Function = null):Boolean
        {
            if (s_dataParser != null)
            {
                return true;
            }

            s_dataParser = new DataParser(s_pinyinDict, completeCallback);

            var loader:URLLoader = new URLLoader();
            loader.dataFormat = URLLoaderDataFormat.BINARY;
            loader.addEventListener(Event.COMPLETE, loadCompleteHandler);
            loader.load(new URLRequest(dataURL));
            return true;
        }

        /**
         * 获取汉字的完整拼音.<br/>
         * 例如: <br/>
         * 输入"你", 将返回一个数组[ni3], 字母ni是拼音, 数字3是音调(表示第三声). <br/>
         * 输入"的", 将返回一个数组[de5,di4,di2], 因为"的"是多音字, 因此返回一个多元素的数组. 数字5代表轻声. <br/>
         * @param char 汉字字符. 如果是一个汉字字符串, 那么将返回第一个汉字的拼音
         * @return 返回汉字的拼音数组.
         */
        static public function getPinyin(char:String):Array
        {
            var charCode:uint = char.charCodeAt(0);
            return s_pinyinDict[charCode];
        }

        /**
         * 获取名字拼音的首字母. <br/>
         * 例如: 输入"你好吗", 将返回"nhm"; 输入"你", 将返回"n"; 如果输入的是英文单词, 则原样返回;
         * @param name 名字
         * @return 拼音首字母
         */
        static public function getAcronym(name:String):String
        {
            var letters:String = "";
            for (var i:int = 0; i < name.length; ++i)
            {
                var charCode:uint = name.charCodeAt(i);
                var pinyin:Array = s_pinyinDict[charCode];
                if (pinyin == null)
                {
                    if ((97 <= charCode && charCode <= 122) || (65 <= charCode && charCode <= 90))
                    {
                        letters += String.fromCharCode(charCode).toLowerCase();
                    }
                    continue;
                }
                letters += String(pinyin[0]).charAt(0);
            }
            return letters;
        }

        static private function loadCompleteHandler(e:Event):void
        {
            var data:ByteArray = (e.target as URLLoader).data;
            data.uncompress();
            var str:String = data.readUTFBytes(data.bytesAvailable);

            s_dataParser.parseData(str);
        }
    }
}
import com.terrier.utils.WxTicker;

import flash.display.Sprite;
import flash.events.Event;
import flash.utils.Dictionary;


class DataParser
{
    private static const MAX_TIME:int = 15;

    private var _pinyinDict:Dictionary;

    private var _engine:Sprite;

    private var _lines:Array;

    private var _completeCallback:Function;

    public function DataParser(dict:Dictionary, completeCallback:Function):void
    {
        _pinyinDict = dict;
        _completeCallback = completeCallback;
    }

    public function parseData(data:String):void
    {
        _lines = data.split("\r\n");
        startEngine();
    }

    private function startEngine():void
    {
        if (_engine == null)
        {
            _engine = new Sprite();
        }
        _engine.addEventListener(Event.ENTER_FRAME, run);
    }

    private function stopEngine():void
    {
        if (_engine != null)
        {
            _engine.removeEventListener(Event.ENTER_FRAME, run);
            _engine = null
        }
    }

    private function run(e:Event):void
    {
        var ticker:WxTicker = new WxTicker();
        var usedTime:int = 0;
        var n:int = 0;
        while (_lines.length > 0)
        {
            var line:String = _lines.pop();
            var parts:Array = line.split(/\s+/);
            if (parts.length < 2)
            {
                continue;
            }
            var charCode:uint = parseInt(parts[0], 16);
            var pinyinArr:Array = parsePinyin(parts[1]);
            addCharCode(charCode, pinyinArr);
            usedTime += ticker.getTick();
            if (usedTime > MAX_TIME)
            {
                break;
            }
            n++;
        }

        if (_lines.length == 0)
        {
            stopEngine(); // done
            if (_completeCallback != null)
            {
                _completeCallback.call();
            }
        }
        return;
    }

    private function parsePinyin(str:String):Array
    {
        var reg:RegExp = /^\(|\)$/g;
        str = str.replace(reg, "");
        return str.split(",")
    }

    private function addCharCode(charCode:uint, pinyinArray:Array):void
    {
        _pinyinDict[charCode] = pinyinArray;
    }
}
